前置作業1:調用 Pinia store 資料<script></script>
將 LoginStore.js 檔裡的 useLoginStore 方法取出。透過 computed 監控資料更動時就重新渲染畫面的特性,把 Pinia store 剛更新的會員 name 、 email 、 id 給顯示。再運用 mapState 取用 Pinia store 資料。
前置作業2:取得網路請求 axios 的路徑
created 裡的 apiUserResUrl 與 apiUserResIdUrl 是網路請求的路徑。路徑會在提交表單和畫面下方渲染出的口袋清單被使用,為使這兩個函式能取用該變數(全域變數),將之定義於此。created 是 Vue 生命週期中實例創建完成階段,可訪問 data 、 computed 、 watch、 methods 上的方法和數據。此時可把 apiUserResUrl 與 apiUserResIdUrl 在 data 裡的初始值給重新賦值。
vue 的生命週期介紹可以參考此篇文章。
(3-3)動作拆解-表單提交
表單提交只有觸發方法的說明。
1.表單提交的限制
2.導出的資料增加屬性<script></script>
中資料實體增加以下屬性。
3.當表單按鈕「加入口袋」被操作時
event.preventDefault();
處理。<template>
...
<form>
...
<div class="d-flex justify-content-end">
<button
class="btn btn-lg btn-primary mb-4"
type="submit"
@click="submitPucket()">
加入口袋
</button>
</div>
</form>
...
</template>
<script>
import axios from "axios";
import { mapState } from "pinia";
// 定義好的 store 賦值給變數 useLoginStore
// 在元件中引入並呼叫 useLoginStore() 來訪問 store
import { useLoginStore } from "../../components/LoginStore.js";
export default {
data() {
return {
restaurants: [],
filterRes: {
filterBrandName: [],
filterType: [],
filterAddress: [],
},
tempRes: {
selectBrandName: "",
selectType: "",
},
saveRes: {
saveBrandName: "",
saveType: "",
saveAddress: "",
},
...
apiUserResUrl: "",
apiUserResIdUrl: "",
...
};
}
methods: {
...
submitPucket() {
event.preventDefault();
if (
(this.saveRes.saveBrandName !== "") &
(this.saveRes.saveAddress !== "") &
(this.saveRes.saveType !== "")
) {
axios.get(this.apiUserResUrl)
.then((res) => {
// res.data是陣列要變成物件後面才能用push,所以取第一個內容(這裡是物件)
const userData = res.data[0];
const newRestaurant = {
brandName: this.saveRes.saveBrandName,
address: this.saveRes.saveAddress,
type: this.saveRes.saveType,
};
// 使用陣列方法 some 檢查會員餐廳API是否有已存在的brandName
const exists = userData.userRestaurants.some(
(item) => item.brandName === newRestaurant.brandName
);
if (!exists) {
userData.userRestaurants.push(newRestaurant);
alert("口袋添加成功");
return axios.put(apiUserResIdUrl, userData);
} else {
alert("該餐廳已存在!");
}
})
.catch((error) => {
console.log(error);
alert("口袋添加失敗");
});
} else {
alert("欄位不可空值!");
}
}
this.tempRes.selectType = "";
this.tempRes.selectBrandName = "";
this.filterRes.filterAddress = "";
},
...
created() {
this.apiUserResUrl = `http://localhost:3002/userRes?email=${this.userEmail}`;
this.apiUserResIdUrl = `http://localhost:3002/userRes/${this.userId}`;
}
},
...
// 監聽data
computed: {
...mapState(useLoginStore, {
// 'name' 是 store 中的狀態名,'userName' 是在組件中的名稱
userName: (state) => state.name,
userEmail: (state) => state.email,
userId: (state) => state.id,
}),
},
};
</script>
附上用 axios.put() 回寫到會員餐廳 API 結果。